<template>
  <div class="employees-container">
    <!-- 头部 -->
    <el-card class="head-card">
      <el-row type="flex" justify="space-between">
        <el-col :span="4">
          <div class="info-box">
            <i class="el-icon-info" />
            <span>共16条记录</span>
          </div>
        </el-col>
        <el-col class="right-col" :span="6">
          <el-button
            v-if="checkMenPermission('import')"
            @click="toimport"
            type="warning"
            >导入</el-button
          >
          <el-button @click="exportData" type="danger">导出</el-button>
          <el-button @click="newemployee" type="primary">新增员工</el-button>
        </el-col>
      </el-row>
    </el-card>
    <!-- 底部 -->
    <el-card class="bottom-card">
      <!-- table -->
      <el-table
        v-loading="loading"
        :data="tableData"
        border
        style="width: 100%"
      >
        <el-table-column type="index" label="序号" width="150" />
        <el-table-column prop="username" sortable label="姓名" width="150" />
        <el-table-column prop="workNumber" sortable label="工号" width="150" />
        <!-- formatter,用来格式化内容Emelent-table的方法 -->
        <el-table-column
          prop="formOfEmployment"
          sortable
          label="聘用形式"
          width="150"
          :formatter="formatter"
        />
        <el-table-column
          prop="departmentName"
          sortable
          label="部门"
          width="150"
        />

        <el-table-column
          prop="timeOfEntry"
          sortable
          label="入职时间"
          width="150"
        >
          <!-- 注意这里需要放在el-table-column标签里面去 -->
          <template #default="{ row }">
            {{ row.timeOfEntry | formatDate }}
          </template>
        </el-table-column>
        <!-- 这几个字段莫有哦 -->
        <el-table-column
          prop="mobile"
          sortable
          label="账户状态(万元)"
          width="150"
        />
        <el-table-column sortable label="是否在职" width="150" />
        <el-table-column label="操作" width="280" fixed="right">
          <!-- @click="remove(row.id)"这个点击事件需要带id,所以上面需要用作用域插槽 -->
          <!-- 能获取到当前这一样的数据 -->
          <template #default="{row}">
            <el-button
              v-if="checkMenPermission('datail')"
              type="text"
              size="small"
              @click="toDatail(row.id)"
              >查看</el-button
            >
            <el-button type="text" size="small">转正</el-button>
            <el-button type="text" size="small">调岗</el-button>
            <el-button type="text" size="small">离职</el-button>
            <el-button @click="toRole(row.id)" type="text" size="small"
              >角色</el-button
            >
            <el-button
              v-if="checkPointPermission('employees-delete')"
              type="text"
              size="small"
              @click="remove(row.id)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页分页分页分页 -->
      <!-- :current-page.sync="page" sync就是可以自动修改页面page的值 ,如果不加,就需要自己去修改页面的值-->
      <el-pagination
        :current-page.sync="page"
        :page-size.sync="pagesize"
        layout="prev, pager, next"
        :total="total"
      />
    </el-card>
    <!-- 7月17号,使用子组件的employeeDialog弹框 -->
    <employeeDialog ref="Dialog"></employeeDialog>
    <!-- 7月22号,使用了组件roleDialog弹框 -->
    <roleDialog ref="roleDialog"></roleDialog>
  </div>
</template>

<script>
// 7月17号----------------------------月17号-----------------------
// 导入抽取的对应关系 (枚举)
// 为什么要用(枚举)???, 为什么要把数字和文字的对应关系抽取出来,直接在页面中写死不好吗
// 功能上两者是没有区别,抽取出来之后,任意的地方要使用,(方便修改)
import EmployeesEnum from '../../api/constant/employees.js'
// 导入获取员工列表的接口
import { getEmployees } from '../../api/employees.js'
// 导入employeeDialog弹框页面
import employeeDialog from './components/employeeDialog.vue'
// 7月22号----------------------------7月22号----------------------------
// 导入roleDialog弹框页面
import roleDialog from './components/roleDialog.vue'
// 导入删除员工的接口
import { delEmployeeById } from '../../api/employees.js'
// 7月17号----------------------------月17号----------------------------
// 元素显示控制这两个判断呢???有一点小bug,,,,这两个判断都是在employees\index.vue 固定写了(就是这两个checkPointPermission,checkMenPermission)
// 那其他页面也是可能需要用到的,像工资页面, 等等也可能需要用到,
// 用工具函数,但是工具函数的逻辑都是固定的,就是不依赖其他的东西,
// 但是这两个判断是依赖了vuex仓库中的数据,所以就不能使用工具函数,
// 但是可以把vue组件里面的某一些逻辑抽出来使用,然后可以合并都其他任何一个组件上的方法, 就是,mixin,使用混入来抽取这部分逻辑
// 然后哪一个页面需要使用,就直接`混进去,`mixin`可以轻松的合并到任何一个组件
// 111,导入mixins混入
// import mixins from '../../mixins/index.js'
export default {
  components: {
    employeeDialog,
    roleDialog
  },
  // mixins: [mixins], // 合入mixins混入
  name: 'Employees',

  data () {
    return {
      tableData: [], // table的数据
      total: 0, // 总条数
      page: 1, // 页码
      pagesize: 18, // 页容量
      loading: false
    }
  },
  // 结合分页组件完成数据的分页,展示效果,
  // 但是,限制:不能使用`@current-change`来完成(Emelent-Pagination 分页里面定义的方法)
  // 侦听器(vue提供了一个侦听器,观察数据和数据改变后才之前的回调函数)
  // page就是需要侦听的数据
  watch: {
    // 分页改变是触发
    page (val) {
      // console.log('val', val)
      this.getData()
    }
  },
  created () {
    this.getData()
  },
  // 7月17号----------------------------月17号----------------------------
  // 点击跳转到views/import/index.vue这个页面,(然后里面又导入了components/UploadExcel/index.vue(导入文件的页面和功能))
  // 所以点击后显示的页面就能使用导入文件的功能了
  methods: {
    // 判断某些用户是否有删除员工的权限
    // 流程
    // 111,权限管理页面配置好权限
    // 加一个删除的权限,(相当于是对这个上传的操作,做一个限制,)删除是在员工管理的下面添加的,
    // 222,然后公司设置里面给角色分配权限,
    // 给人事经理条件删除员工的权限,  人事专员就给权限
    // 333,然后员工页面给用户添加角色权限
    // 罗晓晓分配的是人事经理(有删除员工的权限, 凌凌漆分配的是人事专员,没有删除的权限)
    // 444,罗晓晓登陆后,<在控制台的uesr/setUserInfo打开后,点击vuex里面的user/userInfo/roles/menus,里面有一个和menus是兄弟的属性points,,,points数组,里面就是employees-delete这个字段>
    // 凌凌漆登陆后就没有,
    // 555,操作级别的判断, 用vuex仓库中的, state.user.userInfo.roles.points去判断
    // 和指定的标记去配备,有就返回true,  没有就false 根据这个是判断显示还是隐藏
    // 接收的参数就定义为points,方便阅读哦
    // 在删除的按钮中 定义了 v-if="checkPointPermission('employees-delete')"
    checkPointPermission (points) {
      // console.log('points', points)
      if (!this.$store.state.user.userInfo.roles) {
        return
      }
      const _points = this.$store.state.user.userInfo.roles.points
      // includes是否包含有这个值
      return _points.includes(points)
    },
    // 7月23号----------------------------月23号----------------------------
    // checkMenPermission意思是检测菜单的权限,
    // 定义了一个方法,  v-if="checkMenPermission('datail')",v-if="checkMenPermission('import')"
    // 这个方法里面的传递的参数就是 datail ,import 通过参数去判断是否和menus数组里面有相通同的元素
    // 如果有就说明可以访问,如果没有就不不不能访问,在公司设置的页面分配好对应的权限,就很明显查看
    checkMenPermission (menu) {
      // 注意----这里如果在员工页面退出的速度很快,那么是不会报错 Cannot read property 'menus' of undefined这个提示的
      // 因为代码还没有执行到这里,所以(最好是加一个判断)
      if (!this.$store.state.user.userInfo.roles) {
        return
      }
      const _menus = this.$store.state.user.userInfo.roles.menus
      return _menus.includes(menu)
      // ------------------------------------------------------------------------
      // 写法222,,,if的代码注释后就不报错,中间随便给一写代码,报错就没有了,为什么,不知道
      // const _menus = this.$store.state.user.userInfo.roles.menus
      // // if (!this.$store.state.user.userInfo.roles) {
      // //   return
      // // }
      // // const _menus = this.$store.state.user.userInfo.roles.menus
      // // const _menus = this.$store.state.user.userInfo.roles.menus
    },
    // 7月22号----------------------------7月22号----------------------------
    // 使用的子组件绑定一了ref  <roleDialog ref="roleDialog"></roleDialog>
    // 然后点击的时候把当前这一行的id传递到 roleDialog这个子组件里面(因为子组件需要用这个id去获取数据)，然后调用了里面的lin方法
    toRole (id) {
      this.$refs.roleDialog.lin(id)
    },
    // 查看的点击事件(点击去详情)
    toDatail (id) {
      // 这是vue的编程式导航
      // https://router.vuejs.org/guide/
      // router里面path: '/datail/:id',
      // 去这种/:id'注册的路由，用name  不需要/
      // this.$router.push({ name: '/datail', params: { id } })
      this.$router.push({ name: 'datail', params: { id } })
    },
    // 7月19号----------------------------月19号----------------------------
    // 导出的点击事件
    exportData () {
      import('@/vendor/Export2Excel.js').then(excel => {
        // // 111,自定义数据,表头tHeader和data数据必须定义(测试逻辑的时候用)
        // 注意这里的data定义数据的时候,必须用二维数组(这是官网定义的)
        // 注意,对应关系,id对应9527,name对应唐伯虎,age对应19
        // const tHeader = ['id', 'name', 'age']
        // const data = [
        //   ['9527', '唐伯虎', '19'],
        //   ['9528', '秋香', '18']
        // ]
        // -----------------------------------------------
        // 222,服务器数据(注意目前这样只能拿到第一页的数据,如果想要获取更多,需要把pagesize: 5, // 页容量加大即可)
        // 第一步在控制台vue组件里面打开Employees,然后找到里面的tableData的数据
        // 然后表头就是任何一个对象里面的所有key值this.tableData[0],(这又是一个对象,相等于是数组加索引去对象)
        // 所以取所有的key用 Object.keys表头(优势是必直接去遍历会简单写)
        const tHeader = Object.keys(this.tableData[0])
        // 数据,使用二维数组,先声明一个空数组去存储
        const data = []
        // 然后需要把所有的数据进行遍历(去把对象转成数组)
        // this.tableData就是需要遍历的数组,
        this.tableData.forEach(item => {
          // item是遍历出来的每一个对象,(用v也一样)(遍历出来就是对应到控制台vue组件里面打开Employees,然后找到里面的tableData的数据里面的每一项)
          // 保存没一个对象数据的数组
          const _arr = []
          // 然后需要挨个取出里面的值,取出的item也是一个数组,所以在来一个forEach
          // 再次遍历取出每一项item对应的值 比如(correctionTime:"2018-11-30" formOfEmployment:1)
          // 所以这里的item就是correctionTime: key就是"2018-11-30"
          Object.keys(item).forEach(key => {
            // (item[key])就等于是 传入了属性名correctionTime 取出了里面的"2018-11-30"值
            // _arr.push(item[key])就相当于是把对象里面的每一个属性都取出来了(然后存储在_arr这个数组里面)
            _arr.push(item[key])
          })
          // 数据处理完成后,放在最外面的数组
          data.push(_arr)
        })
        // console.log('data', data) // 打印看看是否处理完成
        // 注意加分析,如果是特别大量的数据导出一般会由后端来生成`excel`,给我们链接并下载
        // 成功,导出
        excel.export_json_to_excel({
          header: tHeader, //表头 必填
          data, //具体数据 必填
          filename: 'excel-list', //文件名字 非必填
          autoWidth: true, //自动宽度 非必填
          bookType: 'xlsx' //类型 非必填
        })
      })
    },
    // 7月19号----------------------------月19号----------------------------
    // 点击导入,跳转到import导入数据的页面
    toimport () {
      this.$router.push({ path: '/import', query: { type: 'employee' } })
      // this.$router.push('/import')
    },
    // 使用了`@current-change`来完成(Emelent-Pagination 分页里面定义的方法)
    // currentPage 改变时会触发,就是分页改变是触发的回调函数
    // handleCurrentChange () {
    //   this.getData()
    // },
    // -----------------------------------------------------
    // 获取员工列表的数据
    async getData () {
      this.loading = true
      const res = await getEmployees({ page: this.page, size: this.pagesize })
      // console.log('res', res)
      this.tableData = res.rows
      this.total = res.total
      setTimeout(() => {
        this.loading = false
      }, 300)
    },
    // 使用`table`提供的`formatter`完成(Emelent官网定义的方法,,用来格式化内容)
    // 定义table的数据渲染方法(:formatter="formatter")
    formatter (row) {
      // console.log('row', row) // 可以打印当前这一行的信息
      // 要处理的就是这一样里面的 formOfEmployment:1
      // hireType 就是api/constant/employees.js里面的一个数组
      // find方法获取数据 作用:类似于filter,也是传入一个回调函数,如果要这个元素,就返回一个true
      // 不要就是fasle, 他会返回满足要求的第一个元素(filter是找很多个,find就只找一个)
      // const res = EmployeesEnum.hireType.find(v => {
      //   return v.id === row.formOfEmployment
      // })
      // return res.value
      // -------------------------------------
      // filter方法获取数据
      const res = EmployeesEnum.hireType.filter(v => {
        // 判断是全等,一定需要给+, 隐式转换一下
        // 如果这里不给+, 那么子组件的submitForm方法提交的数据就不能显示到页面上
        // 或者给一个== 不要给全等
        if (v.id === +row.formOfEmployment) {
          return true
        } else {
          return false
        }
      })
      // 打印出来可以得知,filter返回的是数组,就算只有一个元素,也是返回数组
      // 数组里面的内容 id: 1  value: "正式"(所以返回他的value值)
      // console.log('res', res)
      return res[0].value
    },
    // 点击新增员工
    newemployee () {
      // 注意必须在导入的子组件的标签里面定义 ref="Dialog",然后才可以通过$refs点出子组件的方法
      this.$refs.Dialog.visible = true
    },
    // 单击删除员工
    remove (id) {
      // console.log('id', id)
      delEmployeeById(id)
      this.$message.success('删除成功')
      // 判断一下
      if (this.tableData.length === 1 && this.page > 1) {
        this.page--
      }
      this.getData()
    }
  }
}
</script>

<style lang="scss">
.employees-container {
  padding: 20px;
  // 头部
  .head-card {
    .right-col {
      text-align: right;
    }
    .info-box {
      display: inline-block;
      height: 100%;
      border: 1px solid #91d5ff;
      border-radius: 4px;
      line-height: 40px;
      padding: 2px 10px;
      background-color: #e6f7ff;
      i {
        margin-right: 5px;
        color: #409eff;
        font-size: 20px;
      }
      span {
        font-size: 18px;
      }
    }
  }
  // 底部
  .bottom-card {
    margin-top: 20px;
    .el-pagination {
      text-align: center;
      margin-top: 20px;
    }
  }
  .el-table {
    thead {
      th {
        background: #f3f3f3;
      }
    }
  }
}
</style>
